﻿using Caliburn.Micro;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.Infrastructure.WPF.Extensions;
using SD.IOC.Core.Mediators;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading.Tasks;
using SlamDunk.MES.IAppService.DTOs.Inputs;
using SlamDunk.MES.IAppService.DTOs.Outputs.ExecutionContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.ResourceContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.StockContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.ValueObjects.Enums;

namespace SlamDunk.MES.Client.ViewModels.Execution
{
    /// <summary>
    /// 工单弹出层物料投入ViewModel
    /// </summary>
    public class ActualInputMaterialsViewModel : ScreenBase
    {
        #region # 字段及构造器
        /// <summary>
        /// 作业管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IExecutionContract> _iExecutionContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public ActualInputMaterialsViewModel(ServiceProxy<IExecutionContract> iExecutionContract, IWindowManager windowManager)
        {
            this._iExecutionContract = iExecutionContract;
            this._windowManager = windowManager;
        }

        #endregion

        #region 属性
        #region 工单物料要求列表
        /// <summary>
        /// 工单物料要求列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<WorkOrderMaterialAskInfo> WorkOrderMaterialAsks { get; set; }
        #endregion

        #region 工单实际物料列表
        /// <summary>
        /// 工单实际物料列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<WorkOrderActualMaterialInfo> WorkOrderActualMaterials { get; set; }
        #endregion

        #region 工单Id
        /// <summary>
        /// 工单Id
        /// </summary>
        [DependencyProperty]
        public Guid WorkOrderId { get; set; }
        #endregion

        #region 工厂模型Id
        /// <summary>
        /// 工厂模型Id
        /// </summary>
        [DependencyProperty]
        public Guid? FacilityId { get; set; }
        #endregion
        #endregion

        #region 方法

        #region 加载 —— async Task Load(WorkOrderInfo workOrderInfo)
        /// <summary>
        /// 加载
        /// </summary>
        public async Task Load(WorkOrderInfo workOrderInfo)
        {
            WorkOrderId = workOrderInfo.Id;
            FacilityId = workOrderInfo.FacilityId;
            var WorkOrderMaterialAskList = await Task.Run(() => this._iExecutionContract.Channel.GetWorkOrderMaterialAsks(
                 workOrderInfo.Id));
            WorkOrderMaterialAsks = new ObservableCollection<WorkOrderMaterialAskInfo>(WorkOrderMaterialAskList.Where(x => x.DirectionType == MaterialDirectionType.Input));

            IEnumerable<WorkOrderActualMaterialInfo> workOrderActualMaterialList = await Task.Run(() => this._iExecutionContract.Channel.GetWorkOrderActualMaterials(
                 workOrderInfo.Id));
            WorkOrderActualMaterials = new ObservableCollection<WorkOrderActualMaterialInfo>(workOrderActualMaterialList.Where(x => x.DirectionType == MaterialDirectionType.Input));

        }
        #endregion

        #region 添加物料
        /// <summary>
        /// 添加物料
        /// </summary>
        public async void CreateMaterial()
        {
            AddActualMaterialsViewModel viewModel = ResolveMediator.Resolve<AddActualMaterialsViewModel>();
            viewModel.Load(FacilityId);
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                WorkOrderActualMaterial(
                    viewModel.MaterialNo,
                    viewModel.SelectedMaterial.Name,
                    viewModel.SelectedMaterialLot?.SupplierNo,
                    viewModel.SelectedMaterialLot?.SupplierName,
                    viewModel.SelectedMaterialLot?.ProductionBatchNo,
                    viewModel.SelectedMaterial.Id,
                    viewModel.SelectedMaterialLot?.Id,
                    viewModel.Quantity,
                    viewModel.Sort,
                    viewModel.Description
                    ); ;
            }
        }
        #endregion

        #region 删除工单实际物料
        /// <summary>
        /// 删除工单实际物料
        /// </summary>
        public async void RemoveWorkOrderActualMaterial(WorkOrderActualMaterialInfo workOrderActualMaterialInfo)
        {
            this.Busy();
            //删除工单实际物料
            WorkOrderActualMaterials.Remove(workOrderActualMaterialInfo);
            this.Idle();
        }
        #endregion

        #region 创建实际物料 —— async Task WorkOrderActualMaterial()
        /// <summary>
        /// 创建实际物料
        /// </summary>
        /// param name="code">物料编号</param>
        /// <param name="name">物料名称</param>
        /// <param name="supplierNo">供应商编号</param>
        /// <param name="supplierName">供应商名称</param>
        /// <param name="productionBatchNo">物料批次</param>
        /// <param name="materialId">物料定义Id</param>
        /// <param name="materialLotId">物料批次Id</param>
        /// <param name="quantity">数量</param>
        /// <param name="sort">排序</param>
        /// <param name="description">描述</param>
        public void WorkOrderActualMaterial(string code, string name, string supplierNo, string supplierName, string productionBatchNo, Guid materialId, Guid? materialLotId, decimal quantity, int sort, string description)
        {
            WorkOrderActualMaterialInfo workOrderActualMaterialInfo = new WorkOrderActualMaterialInfo();
            workOrderActualMaterialInfo.MaterialId = materialId;
            workOrderActualMaterialInfo.MaterialLotId = materialLotId;
            workOrderActualMaterialInfo.MaterialInfo = new MaterialInfo() { Number = code, Name = name };
            workOrderActualMaterialInfo.MaterialLotInfo = new MaterialLotInfo() { SupplierNo = supplierNo, SupplierName = supplierName, ProductionBatchNo = productionBatchNo };
            workOrderActualMaterialInfo.Quantity = quantity;
            workOrderActualMaterialInfo.Sort = sort;
            workOrderActualMaterialInfo.Description = description;
            WorkOrderActualMaterials.Add(workOrderActualMaterialInfo);
        }
        #endregion

        #region 提交 —— async void Submit()
        /// <summary>
        /// 提交
        /// </summary>
        public async void Submit()
        {
            #region # 验证

            #endregion

            List<WorkOrderActualMaterialParam> workOrderActualMaterialParamList = new List<WorkOrderActualMaterialParam>();
            foreach (var workOrderActualMaterial in WorkOrderActualMaterials)
            {
                WorkOrderActualMaterialParam workOrderActualMaterialParam = new WorkOrderActualMaterialParam();
                workOrderActualMaterialParam.materialId = workOrderActualMaterial.MaterialId;
                workOrderActualMaterialParam.materialLotId = workOrderActualMaterial.MaterialLotId;
                workOrderActualMaterialParam.quantity = workOrderActualMaterial.Quantity;
                workOrderActualMaterialParam.sort = workOrderActualMaterial.Sort;
                workOrderActualMaterialParam.description = workOrderActualMaterial.Description;
                workOrderActualMaterialParamList.Add(workOrderActualMaterialParam);
            }
            this.Busy();
            await Task.Run(() => this._iExecutionContract.Channel.SaveWorkOrderActualInputMaterials(
                WorkOrderId, workOrderActualMaterialParamList));
            await base.TryCloseAsync(true);
            this.Idle();
        }
        #endregion

        #endregion
    }
}
